package com.starsoft.quant.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.starsoft.frame.base.bean.BaseAcount;
import com.starsoft.frame.base.bean.BaseUser;
import com.starsoft.frame.base.dao.AcountDao;
import com.starsoft.frame.base.dao.UserDao;
import com.starsoft.frame.util.DateUtil;
import com.starsoft.frame.util.StringUtil;
import com.starsoft.quant.bean.ModelContext;
import com.starsoft.quant.bean.QuantAcount;
import com.starsoft.quant.bean.QuantModel;
import com.starsoft.quant.dao.QuantAcountDao;
import com.starsoft.quant.dao.QuantModelDao;
import com.starsoft.quant.executor.ExecutorContext;
import com.starsoft.smdc.bean.SmdcSecurity;
import com.starsoft.smdc.service.HolidayService;
import com.starsoft.smdc.service.SecurityService;
import com.starsoft.trade.bean.TradeAcount;
import com.starsoft.trade.dao.TradeAcountDao;
import com.starsoft.trade.service.TradeAcountService;

@Service
public class QuantAcountService {
	
	@Autowired
	UserDao userDao;

	@Autowired
	AcountDao baseAcountDao;
	
	@Autowired
	QuantAcountDao quantAcountDao;
	
	@Autowired
	TradeAcountDao tradeAcountDao;
	
	@Autowired
	QuantModelDao modelDao;
	
	@Autowired
	ModelParamsService paramsService;
	
	@Autowired
	TradeAcountService tradeAcountService;
	
	@Autowired
	HolidayService holidayService;
	
	@Autowired
	SecurityService securityService;
	
	public ModelContext getModelContext(Integer acountId){
		ModelContext modelContext = new ModelContext();
		BaseAcount baseAcount = baseAcountDao.get(acountId);
		BaseUser user = userDao.getUser(baseAcount.getUserId());
		TradeAcount tradeAcount = tradeAcountDao.get(acountId);
		QuantAcount quantAcount = quantAcountDao.get(acountId);
		QuantModel model =modelDao.get(quantAcount.getModelCode());
		
		modelContext.setUser(user);
		modelContext.setAcount(baseAcount);
		modelContext.setTradeAcount(tradeAcount);
		modelContext.setQuantAcount(quantAcount);
		modelContext.setModel(model);
		modelContext.setModelParamList(paramsService.getAcountModelParams(quantAcount));
		return modelContext;
	}

	public QuantModel getModel(Integer acountId) {
		QuantAcount quantAcount = quantAcountDao.get(acountId);
		if (quantAcount!=null && quantAcount.getModelCode() != null) {
			return modelDao.get(quantAcount.getModelCode());
		} else {
			return null;
		}
	}
	
	public QuantAcount getAcount(Integer acountId){
		 return quantAcountDao.get(acountId);
	}
	
	public void saveAcount(QuantAcount quantAcount){
		TradeAcount tradeAcount = tradeAcountService.get(quantAcount.getAcountId());
		if(tradeAcount==null){
			throw new RuntimeException("无交易账户，请先创建！");
		}
		if(quantAcount.getStartDate()==null){
			throw new RuntimeException("开始日期不能为空！");
		}
		Date initDate = tradeAcount.getInitDate();
		if(!initDate.before(quantAcount.getStartDate())){
			Date startDate = holidayService.getNextBusinessDay(initDate, 1);
			quantAcount.setStartDate(startDate);
		}
		quantAcountDao.saveOrUpdate(quantAcount);
	}
	
	public List<QuantAcount> geAcounts(){
		 return quantAcountDao.getAll();
	}
	
	public void delete(QuantAcount quantAcount){
		quantAcountDao.delete(quantAcount);
	}
	
	public boolean canBackTest(Integer acountId) {
		TradeAcount tradeAcount = tradeAcountService.get(acountId);
		if (!StringUtil.isEmpty(tradeAcount.getExSystem())) {
			return false;
		} else if (Boolean.TRUE.equals(tradeAcount.getRealAcount())) {
			return false;
		} else {
			return true;
		}
	}
	
	public boolean hasExSystem(Integer acountId) {
		TradeAcount tradeAcount = tradeAcountService.get(acountId);
		if (StringUtil.isEmpty(tradeAcount.getExSystem())) {
			return false;
		} else {
			return true;
		}
	}
	
	public String getSecList(Integer acountId){
		QuantModel model = getModel(acountId);
		QuantAcount acount = getAcount(acountId);
		String secList = model.getSecList();
		String secListAcount = acount.getSecList();
		String result = null;
		if (!StringUtil.isEmpty(secListAcount)) {
			result = secListAcount;
		} else if (!StringUtil.isEmpty(secList)) {
			result = secList;
		}
		return result;
	}
	
	public List<SmdcSecurity> getModelSecList(Integer acountId) {
		String secList = this.getSecList(acountId);
		List<SmdcSecurity> securityList = null;
		if (!StringUtil.isEmpty(secList)) {
			if (secList.contains("from")) {
				securityList = securityService.find(secList);
			} else {
				List<String> secIds = Arrays.asList(secList.split(","));
				List<String> secIdsNew = new ArrayList<>();
				secIds.forEach(secId->secIdsNew.add(secId.trim()));
				securityList = securityService.get(secIdsNew);
			}
			return securityList;
		} else {
			return null;
		}
	}

	public void updateLastBackTest(QuantAcount quantAcount){
		quantAcount.setLastBackTest(DateUtil.getTimestamp());
		quantAcountDao.saveOrUpdate(quantAcount);
	}
	
}
